#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>

int fd;
volatile sig_atomic_t got_sigio = 0;

void sig_handler(int signo) {
    if (signo == SIGIO) {
        got_sigio = 1;
    }
}

int main() {
    struct sigaction sa;
    
    // 打开文件
    fd = open("input.txt", O_RDONLY | O_NONBLOCK);
    if (fd == -1) {
        perror("open failed");
        exit(EXIT_FAILURE);
    }
    
    // 设置信号处理函数
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = sig_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGIO, &sa, NULL) == -1) {
        perror("sigaction failed");
        close(fd);
        exit(EXIT_FAILURE);
    }
    
    // 设置文件所有者为当前进程（SIGIO信号发送目标）
    if (fcntl(fd, F_SETOWN, getpid()) == -1) {
        perror("fcntl F_SETOWN failed");
        close(fd);
        exit(EXIT_FAILURE);
    }
    
    // 设置文件为信号驱动I/O模式
    int flags = fcntl(fd, F_GETFL);
    if (flags == -1) {
        perror("fcntl F_GETFL failed");
        close(fd);
        exit(EXIT_FAILURE);
    }
    
    if (fcntl(fd, F_SETFL, flags | O_ASYNC) == -1) {
        perror("fcntl F_SETFL failed");
        close(fd);
        exit(EXIT_FAILURE);
    }
    
    printf("等待input.txt有新数据...\n");
    
    // 主循环处理信号
    while (1) {
        // 等待信号
        pause();
        
        if (got_sigio) {
            got_sigio = 0;
            printf("收到SIGIO信号，文件有新数据\n");
            
            char buf[1024];
            ssize_t nbytes;
            
            // 循环读取所有可用数据
            while ((nbytes = read(fd, buf, sizeof(buf) - 1)) > 0) {
                buf[nbytes] = '\0';
                printf("读取内容: %s\n", buf);
            }
            
            if (nbytes == -1 && errno != EAGAIN) {
                perror("read failed");
                break;
            } else if (nbytes == 0) {
                printf("文件已结束\n");
                break;
            }
        }
    }
    
    close(fd);
    return 0;
}